package com.liang.response.core;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.liang.response.constants.ResultHeaderConstants;
import com.liang.response.domain.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 导演
 *
 * @author liangyehao
 * @date 2021/04/26
 */
public class Director {

    public static String doWork(String filePath, File basicFile, String startTimeStr, String endTimeStr) throws FileNotFoundException {

        long startTime = System.currentTimeMillis();

        List<Detail> filteredData = filterData(basicFile);

        System.out.println("1.filteredData:" + filteredData.size());

        DateTime start = DateUtil.parse(startTimeStr);
        DateTime end = DateUtil.parse(endTimeStr);

        List<Detail> selectData = selectData(start, end, filteredData);

        System.out.println("2.selectData:" + selectData.size());

        List<AgentResult> agentResult = countByAgent(selectData);

        List<StoreResult> storeResult = countByStore(selectData);


        //格式化格式
        String format = "YYYYMMddHHmmss";
        // DateTimeFormatter.ofPattern方法根据指定的格式输出时间
        String formatDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));

        String fileName = filePath+startTimeStr+"~"+endTimeStr+"响应率统计(23秒)" + formatDateTime + ".xlsx";

        FileOutputStream outputStream = new FileOutputStream(fileName);
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();

        WriteSheet mainSheet = EasyExcel.writerSheet(0, "处理后明细").head(Detail.class).build();
        excelWriter.write(filteredData,mainSheet);

        WriteSheet agentSheet = EasyExcel.writerSheet(1, "经纪人响应").head(AgentResult.class).build();
        excelWriter.write(agentResult,agentSheet);

        WriteSheet storeSheet = EasyExcel.writerSheet(2, "门店响应").head(StoreResult.class).build();
        excelWriter.write(storeResult,storeSheet);

        excelWriter.finish();
        System.out.println("共处理了: "+filteredData.size()+" 条数据,耗时: " + (System.currentTimeMillis() - startTime)/1000 + "s");

        return fileName;
    }

    private static List<StoreResult> countByStore(List<Detail> selectData) {
        List<StoreResult> storeData = new ArrayList<>();
        // 按门店分组
        Map<String, List<Detail>> stores = selectData.stream()
                .collect(Collectors.groupingBy(Detail::getStores));

        for (Map.Entry<String, List<Detail>> entry : stores.entrySet()) {
            String storeName = entry.getKey();
            List<Detail> total = entry.getValue();
            StoreResult result = new StoreResult();
            result.setStore(storeName);
            storeData.add(buildResult(total,result));
        }
        List<StoreResult> sorted = storeData.stream().sorted(Comparator.comparing(StoreResult::getStore)).collect(Collectors.toList());

        // 总计
        StoreResult storeResult = new StoreResult();
        storeResult.setStore("总计");
        StoreResult storeSumResult = buildResult(selectData, storeResult);
        sorted.add(storeSumResult);

        return sorted;
    }


    private static List<AgentResult> countByAgent(List<Detail> selectData) {
        List<AgentResult> agentData = new ArrayList<>();
        // 按经纪人分组
        Map<String, List<Detail>> agents = selectData.stream()
                .collect(Collectors.groupingBy(Detail::getAgentName));

        for (Map.Entry<String, List<Detail>> entry : agents.entrySet()) {
            String agentName = entry.getKey();
            List<Detail> total = entry.getValue();
            AgentResult result = new AgentResult();
            result.setAgentName(agentName);
            result.setStore(total.get(0).getStores());

            agentData.add(buildResult(total,result));
        }

        List<AgentResult> sorted = agentData.stream().sorted(Comparator.comparing(AgentResult::getStore)).collect(Collectors.toList());

        // 总计
        AgentResult agentResult = new AgentResult();
        agentResult.setStore("总计");
        AgentResult agentSumResult = buildResult(selectData, agentResult);
        sorted.add(agentSumResult);

        return sorted;
    }

    private static <T extends Result> T buildResult(List<Detail> total,T result){

        List<Detail> bsData = total.stream().filter(detail -> "二手房".equals(detail.getBusinessTypeName())).collect(Collectors.toList());
        List<Detail> rentData = total.stream().filter(detail -> "租房".equals(detail.getBusinessTypeName())).collect(Collectors.toList());
        List<Detail> newData = total.stream().filter(detail -> "新房".equals(detail.getBusinessTypeName())).collect(Collectors.toList());
        List<Detail> otherData = total.stream().filter(detail -> "未知".equals(detail.getBusinessTypeName())).collect(Collectors.toList());

        try {
            result.build(ResultHeaderConstants.TOTAL,CommonIndex.build(total));

            result.build(ResultHeaderConstants.BS,CommonIndex.build(bsData));

            result.build(ResultHeaderConstants.RENT,CommonIndex.build(rentData));

            result.build(ResultHeaderConstants.NEW,CommonIndex.build(newData));

            result.build(ResultHeaderConstants.OTHER,CommonIndex.build(otherData));

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return result;
    }

    private static List<Detail> selectData(DateTime start, DateTime end, List<Detail> list) {
        return list.stream().filter(detail -> {
            Date businessTime = detail.getDateOf();
            DateTime when = DateTime.of(businessTime);
            return when.isAfterOrEquals(start) && when.isBefore(DateUtil.offsetDay(end,1));
        }).collect(Collectors.toList());
    }

    private static List<Detail> filterData(File baseFile) {
        // 读取数据
        DataListener dataListener = new DataListener();

        EasyExcel.read(baseFile, Detail.class, dataListener).sheet().doRead();

        List<Detail> list = dataListener.getList();

        List<Detail> distinctList = list.stream().distinct().collect(Collectors.toList());

        // 过滤数据
        return distinctList.stream()
                .filter(data -> 0 < data.getResponseTime())
                .sorted(Comparator.comparing(Detail::getStores)).collect(Collectors.toList());

    }

    public static void main(String[] args) throws FileNotFoundException {
        String s = "D:\\workspace\\personal\\product\\beike-excel\\excel\\";
        doWork(s,new File(s+"response-basic.xlsx"),"2021-04-26","2021-04-28");
    }


}
